package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.Assert;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.ext.conf.ApplicationConf;
import com.authine.cloudpivot.ext.domain.dto.*;
import com.authine.cloudpivot.ext.domain.vo.*;
import com.authine.cloudpivot.ext.enums.FileExportEnum;
import com.authine.cloudpivot.ext.enums.OrderCustomerStatusEnum;
import com.authine.cloudpivot.ext.enums.PayWayEnum;
import com.authine.cloudpivot.ext.enums.SMSTemplateCodeEnum;
import com.authine.cloudpivot.ext.util.*;
import com.authine.common.util.IdWorker;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.AttachmentFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.query.expression.Operator;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.authine.cloudpivot.ext.conf.ApplicationConf.*;
import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @program: gm-market
 * @description: 商城个人中心
 * @author: wlw
 * @create: 2021-08-21 16:37
 **/
@Path("MarketCenterService")
@Slf4j
public class MarketCenterService extends ApplicationService {
    private JdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(JdbcTemplate.class);
    private StringRedisTemplate redisTemplate = ApplicationContextUtils.getBean(StringRedisTemplate.class);
    private final String SMS_CODE = "SMS_CODE";
    private final String IMG_CODE = "IMG_CODE";



    @POST
    @Path("orderPage")
    @Operation(summary = "个人中心-我的订单", tags = CUSTOM_SERVICE)
    public MultiResponse<OrderPageVo> orderPage(@Parameter OrderPageQuery orderPageQuery){
        Assert.isTrue(!StringUtils.isEmpty(orderPageQuery),"参数不能为空");
        int index  = orderPageQuery.getPageIndex()*(orderPageQuery.getPageSize());
        StringBuilder querySql = new StringBuilder("select " +
                "t1.id," +
                "t1.erp_po," +
                "t2.name," +
                "t2.goods_id," +
                "t2.brand," +
                "t2.vendor_organization_name," +
                "t2.receiver," +
                "t2.phone," +
                "t2.address," +
                "t2.amount," +
                "t2.unit," +
                "t2.quantity," +
                "t2.createdTime," +
                "t2.pretax_price," +
                "t2.images," +
                "t2.price," +
                "t1.order_customer_status," +
                "t1.accept_delivery_time," +
                "t2.order_customer_goods_status," +
                "t2.order_goods_returns_status " +
                "from "+I_ORDERCENTER_CUSTOMERORDER+" t1 join "+I_ORDERCENTER_CUSTOMER_ORDER_GOODS+" t2 on t1.id = t2.order_customer_id where t1.deleted = 0 and t2.deleted=0 and t1.type = 'ShopOrder'");
        StringBuilder countSql = new StringBuilder("select " +
                "count(distinct t1.id) as count" +
                " from "+I_ORDERCENTER_CUSTOMERORDER+" t1 join "+I_ORDERCENTER_CUSTOMER_ORDER_GOODS+" t2 on t1.id = t2.order_customer_id where t1.deleted = 0 and t2.deleted = 0 and t1.type = 'ShopOrder'");
        buildOrderFilter(orderPageQuery, querySql);
        buildOrderFilter(orderPageQuery, countSql);
        querySql.append(" group by id order by t2.createdTime desc").append(" limit ").append(index).append(",").append(orderPageQuery.getPageSize());
        log.info("query执行sql=====》"+querySql.toString());
        List<OrderPageVo> orderPageVos = jdbcTemplate.query(querySql.toString(), (rs, rowNum) ->
                OrderPageVo.builder()
                        .erp_po(rs.getString("erp_po"))
                        .id(rs.getString("id"))
                        .receiver(rs.getString("receiver"))
                        .phone(rs.getString("phone"))
                        .address(rs.getString("address"))
                        .build()
        );
        log.info("count执行sql=====》"+countSql.toString());
        Integer count = jdbcTemplate.queryForObject(countSql.toString(), (rs, rowNum) -> rs.getInt("count"));
        if(CollectionUtils.isEmpty(orderPageVos))return MultiResponse.of(orderPageVos, Optional.ofNullable(count).orElse(0));
        List<String> idList = orderPageVos.stream().map( OrderPageVo::getId).collect(Collectors.toList());
        List<Map<String, Object>> data = BoServiceUtils.findListBySimple(ApplicationConf.CUSTOMER_ORDER_GOODS, "order_customer_id", idList, Operator.IN).getData().getData();
        Map<String, List<OrderGoodsVo>> orderGoodsVoMap = Objects.requireNonNull(BoUtils.copy2List(data, OrderGoodsVo.class)).stream().collect(Collectors.groupingBy(OrderGoodsVo::getOrder_customer_id));
        orderPageVos.forEach(v->{
            if(Objects.nonNull(orderGoodsVoMap.get(v.getId()))){
                v.setOrderGoodsVo(orderGoodsVoMap.get(v.getId()));
                v.getOrderGoodsVo().forEach(t->{
                    t.setShow_status(!StringUtils.isEmpty(t.getOrder_goods_returns_status())?t.getOrder_goods_returns_status():t.getOrder_customer_goods_status());
                    t.setQuantity_return(Optional.ofNullable(t.getQuantity_return_not_shipped()).orElse(BigDecimal.ZERO).add(Optional.ofNullable(t.getQuantity_return_shipped()).orElse(BigDecimal.ZERO)));
                });
            }

        });

        return MultiResponse.of(orderPageVos,Optional.ofNullable(count).orElse(0));
    }

    @POST
    @Path("refundOrderPage")
    @Operation(summary = "个人中心-退款售后", tags = CUSTOM_SERVICE)
    public MultiResponse<RefundOrderVo> refundOrderPage(@Parameter RefundOrderPageQuery refundOrderPageQuery){
        Assert.isTrue(!StringUtils.isEmpty(refundOrderPageQuery),"参数不能为空");
        int index  = refundOrderPageQuery.getPageIndex()*refundOrderPageQuery.getPageSize();
        StringBuilder querySql = new StringBuilder("select " +
                "t1.order_customer_id," +
                "t2.erp_po," +
                "t2.id," +
                "t2.name," +
                "t2.goods_id," +
                "t2.brand," +
                "t1.vendor_organization_name," +
                "t1.memo," +
                "t1.customer_amount," +
                "t1.createdTime," +
                "t1.quantity," +
                "t2.unit," +
                "t2.price," +
                "t2.images," +
                "t2.pretax_price," +
                "t1.order_goods_returns_status " +
                "from "+I_ORDERCENTER_REFUND+" t1 join "+I_ORDERCENTER_CUSTOMER_ORDER_GOODS+" t2 on t1.order_customer_goods_id = t2.id where t1.deleted = 0 and t2.deleted=0");
        StringBuilder countSql = new StringBuilder("select " +
                "count(1) as count" +
                " from "+I_ORDERCENTER_REFUND+" t1 join "+I_ORDERCENTER_CUSTOMER_ORDER_GOODS+" t2 on t1.order_customer_goods_id = t2.id where t1.deleted = 0 and t2.deleted=0");
        buildRefundOrderFilter(refundOrderPageQuery, querySql);
        buildRefundOrderFilter(refundOrderPageQuery, countSql);
        querySql.append(" order by t1.createdTime desc ").append("limit ").append(index).append(",").append(refundOrderPageQuery.getPageSize());
        log.info("count执行sql=====》"+countSql.toString());
        Integer count = jdbcTemplate.queryForObject(countSql.toString(), (rs, rowNum) -> rs.getInt("count"));
        log.info("query执行sql=====》"+querySql.toString());
        List<RefundOrderVo> refundOrderVos = jdbcTemplate.query(querySql.toString(), (rs, rowNum) -> RefundOrderVo.builder().brand(rs.getString("brand"))
                .erp_po(rs.getString("erp_po"))
                .goods_id(rs.getString("goods_id"))
                .id(rs.getString("order_customer_id"))
                .memo(rs.getString("memo"))
                .customer_amount(rs.getBigDecimal("customer_amount"))
                .createdTime(rs.getTimestamp("createdTime"))
                .name(rs.getString("name"))
                .status(rs.getString("order_goods_returns_status"))
                .vendor_organization_name(rs.getString("vendor_organization_name"))
                .orderGoodsId(rs.getString("id"))
                .images(JSON.parseArray(rs.getString("images"), AttachmentFormat.class))
                .price(rs.getBigDecimal("price"))
                .quantity(rs.getBigDecimal("quantity"))
                .unit(rs.getString("unit"))
                .pretax_price(rs.getBigDecimal("pretax_price"))
                .pretax_amount(Optional.ofNullable(rs.getBigDecimal("pretax_price")).orElse(BigDecimal.ZERO).multiply(Optional.ofNullable(rs.getBigDecimal("quantity")).orElse(BigDecimal.ZERO)))
                .build());
        return MultiResponse.of(refundOrderVos,Optional.ofNullable(count).orElse(0));
    }

    @POST
    @Path("confirmReceiving")
    @Operation(summary = "个人中心-确认收货", tags = CUSTOM_SERVICE)
    public SingleResponse confirmReceiving(@Parameter ConfirmReceivingDto confirmReceivingDto){
        Assert.isTrue(!StringUtils.isEmpty(confirmReceivingDto),"参数不能为空");
        Map<String, Object> data = BoServiceUtils.loadByBizObjectId(ApplicationConf.CUSTOMER_ORDER_GOODS, confirmReceivingDto.getId()).getData().getData();
        Assert.isTrue(Objects.nonNull(data),"订单商品不存在");
        String url = PmUtil.getUrl(orderCenter);
        Assert.isTrue(!StringUtils.isEmpty(url),"服务地址获取失败");
        String fullUrl = url.concat(customerReceive);
        Map singleResponse = RestTemplateUtil.rest(fullUrl, confirmReceivingDto, HttpMethod.POST);
        log.info("[confirmReceiving] 响应：{}", JSON.toJSONString(singleResponse));
        SingleResponse response = BoUtils.Map2Bo(singleResponse, SingleResponse.class);
        Assert.isTrue(response.isSuccess(),response.getErrMessage());
        return response;
    }

    @POST
    @Path("customerCancelRefund")
    @Operation(summary = "个人中心-取消退款", tags = CUSTOM_SERVICE)
    public SingleResponse customerCancelRefund(@Parameter List<String> ids){
        Assert.isTrue(!StringUtils.isEmpty(ids),"参数不能为空");
        List<Map<String, Object>> data = BoServiceUtils.findListBySimple(ApplicationConf.CUSTOMER_ORDER_GOODS,"id",ids,Operator.IN).getData().getData();
        Assert.isTrue(Objects.nonNull(data),"订单商品不存在");
        String url = PmUtil.getUrl(orderCenter);
        Assert.isTrue(!StringUtils.isEmpty(url),"服务地址获取失败");
        String fullUrl = url.concat(customerCancelRefund);
        Map singleResponse = RestTemplateUtil.rest(fullUrl, DeleteMallGoodsExport.builder().ids(ids).build(), HttpMethod.POST);
        log.info("[customerCancelRefund] 响应：{}", JSON.toJSONString(singleResponse));
        SingleResponse response = BoUtils.Map2Bo(singleResponse, SingleResponse.class);
        Assert.isTrue(response.isSuccess(),response.getErrMessage());
        return response;
    }

    @POST
    @Path("orderExport")
    @Operation(summary = "个人中心-订单导出", tags = CUSTOM_SERVICE)
    public SingleResponse orderExport(@Parameter ExportDto exportDto){
        Assert.isTrue(Objects.nonNull(exportDto),"参数不能为空");
        Assert.isTrue(!CollectionUtils.isEmpty(exportDto.getIds()),"id不能为空");
        Assert.isTrue(!StringUtils.isEmpty(exportDto.getExportFileType()),"导出文件类型不能为空");
        StringBuilder querySql =new StringBuilder("select " +
                "t1.id," +
                "t1.erp_po," +
                "t2.name," +
                "t2.goods_id," +
                "t2.brand," +
                "t2.vendor_organization_name," +
                "t2.receiver," +
                "t2.phone," +
                "t2.address," +
                "t2.amount," +
                "t1.createdTime," +
                "t1.order_customer_status," +
                "t2.order_customer_goods_status," +
                "t2.order_goods_returns_status," +
                "t1.actual_order," +
                "t2.delivery," +
                "t2.place_order_fullname," +
                "t2.quantity," +
                "t2.price," +
                "t2.total," +
                "t2.model," +
                "t2.spec " +
                "from "+ I_ORDERCENTER_CUSTOMERORDER+" t1 join "+I_ORDERCENTER_CUSTOMER_ORDER_GOODS+" t2 on t1.id = t2.order_customer_id where t1.deleted = 0 and t2.deleted=0 ");;
        querySql.append(" and t1.id in(").append(String.join(",", exportDto.getIds())).append(")");
        List<OrderExportVo> orderExportVos = jdbcTemplate.query(querySql.toString(), (rs, rowNum) ->
                OrderExportVo.builder()
                .brand(rs.getString("brand"))
                .erpPO(rs.getString("erp_po"))
                .goodsId(rs.getString("goods_id"))
                .id(rs.getString("id"))
                .name(rs.getString("name"))
                .model(rs.getString("model"))
                .spec(rs.getString("spec"))
                .memberName(rs.getString("place_order_fullname"))
                .num(rs.getBigDecimal("quantity"))
                .price(rs.getBigDecimal("price"))
                .amount(rs.getBigDecimal("total"))
                .delivery(PmUtil.numberFormat(rs.getBigDecimal("delivery")).doubleValue())
                .orgName(rs.getString("vendor_organization_name"))
                .time(rs.getTimestamp("createdTime"))
                .build()
        );
        ReportRecord record = ReportRecord.builder()
                .code("shop_order_list_report")
                .type(Optional.ofNullable(FileExportEnum.get(exportDto.getExportFileType())).orElseThrow(()->new BizException("文件类型不支持")).getCode())
                .data(orderExportVos.stream().map(BoUtils::bo2Map).collect(Collectors.toList()))
                .build();
        Map singleResponse = RestTemplateUtil.rest(Objects.requireNonNull(PmUtil.getUrl(systemManagement)).concat(EXPORT_REPORT_URL), record, HttpMethod.POST);
        SingleResponse response = BoUtils.Map2Bo(singleResponse, SingleResponse.class);
        Assert.isTrue(response.isSuccess(),response.getErrMessage());
        return  SingleResponse.of(singleResponse.get("data"));
    }


    @POST
    @Path("orderDetailExport")
    @Operation(summary = "个人中心-订单详情导出", tags = CUSTOM_SERVICE)
    public SingleResponse orderDetailExport(@Parameter ExportDto exportDto){
        Assert.isTrue(Objects.nonNull(exportDto),"参数不能为空");
        Assert.isTrue(!CollectionUtils.isEmpty(exportDto.getIds()),"id不能为空");
        Assert.isTrue(!StringUtils.isEmpty(exportDto.getExportFileType()),"导出文件类型不能为空");
        String id = CollectionUtils.firstElement(exportDto.getIds());
        BO customerData = BoServiceUtils.loadByBizObjectId(CUSTOMERORDER, id).getData();
        BOList supplierData = BoServiceUtils.findListBySimple(SUPPLIER_ORDER_GOODS, "order_customer_id", id, Operator.EQ).getData();
        if( Objects.isNull(customerData.getData()) || CollectionUtils.isEmpty(supplierData.getData())){
            log.info("[orderDetailExport] 订单数据不存在，客户订单：{},供应商订单：{}",customerData.getData(),supplierData.getData());
            throw new BizException("订单数据不存在");
        }
        BOList orderGoodsList = BoServiceUtils.findListBySimple(CUSTOMER_ORDER_GOODS, "order_customer_id", id, Operator.EQ).getData();
        if(Objects.isNull(orderGoodsList)||CollectionUtils.isEmpty(orderGoodsList.getData())){
            throw new BizException("客户订单商品数据不存在");
        }
        List<DetailExportVo> exportVos = orderGoodsList.getData().stream().map(t -> DetailExportVo.builder()
                .brand((String) t.get("brand"))
                .id((String) t.get("id"))
                .model((String) t.get("model"))
                .name((String) t.get("name"))
                .num(((BigDecimal) t.get("quantity")).doubleValue())
                .orgName((String) t.get("vendor_organization_name"))
                .price(((BigDecimal) t.get("price")).doubleValue())
                .sku((String) t.get("sku"))
                .spec((String) t.get("spec"))
                .total(((BigDecimal) t.get("total")).doubleValue())
                .unit((String) t.get("unit"))
                .brand((String) t.get("brand"))
                .build()).collect(Collectors.toList());
        Map<String, Object> customerOrder = customerData.getData();
        Map<String, Object> supplierOrder = CollectionUtils.firstElement(supplierData.getData());
        OrderDetailExportVo exportVo = OrderDetailExportVo.builder()
                .address((String) customerOrder.get("address"))
                .erpPO((String) customerOrder.get("erp_po"))
                .financeType(Objects.requireNonNull(PayWayEnum.get((String) customerOrder.get("payment_method"))).getDesc())
                .memberName((String) customerOrder.get("place_order_fullname"))
                .receiver((String) customerOrder.get("receiver"))
                .memo((String) supplierOrder.get("memo"))
                .phone(Long.valueOf((String) customerOrder.get("phone")))
                .postal((String) customerOrder.get("postal"))
                .orgName((String) supplierOrder.get("organization_name"))
                .total(((BigDecimal)customerOrder.get("total")).doubleValue())
                .status(Objects.requireNonNull(OrderCustomerStatusEnum.get((String) customerOrder.get("order_customer_status"))).getDesc())
                .id((String) customerOrder.get("id"))
                .time((String)customerOrder.get("createdTime"))
                .orderGoodsList(exportVos)
                .build();
        ReportRecord record = ReportRecord.builder()
                .code("shop_order_detail_report")
                .type(Optional.ofNullable(FileExportEnum.get(exportDto.getExportFileType())).orElseThrow(()->new BizException("文件类型不支持")).getCode())
                .data(Collections.singletonList(BoUtils.objectToMap(exportVo)))
                .build();
        Map singleResponse = RestTemplateUtil.rest(Objects.requireNonNull(PmUtil.getUrl(systemManagement)).concat(EXPORT_REPORT_URL), record, HttpMethod.POST);
        SingleResponse response = BoUtils.Map2Bo(singleResponse, SingleResponse.class);
        Assert.isTrue(response.isSuccess(),response.getErrMessage());
        return  SingleResponse.of(singleResponse.get("data"));
    }


    @POST
    @Path("queryLogistics")
    @Operation(summary = "个人中心-物流查询", tags = CUSTOM_SERVICE)
    public SingleResponse queryLogistics(@Parameter LogisticsDto logisticsDto){
        Assert.isTrue(Objects.nonNull(logisticsDto),"参数不能为空");
        Assert.isTrue(!StringUtils.isEmpty(logisticsDto.getWaybillNum()),"物流单号不能为空");
        String url = PmUtil.getUrl(orderCenter);
        Assert.isTrue(!StringUtils.isEmpty(url),"服务地址获取失败");
        String fullUrl =url.concat(queryLogistics);
        Map singleResponse = RestTemplateUtil.rest(fullUrl, logisticsDto, HttpMethod.POST);
        log.info("[refund] 响应：{}",JSON.toJSONString(singleResponse));
        SingleResponse response = BoUtils.Map2Bo(singleResponse, SingleResponse.class);
        Assert.isTrue(response.isSuccess(),response.getErrMessage());
        return response;
    }




//-----------------------------------------------------分割线-----------------------------------------------------------------//







    private void buildOrderFilter( OrderPageQuery orderPageQuery, StringBuilder sql) {
        sql.append(" and t1.place_order_user_id like concat('%','").append(RequestContext.getCorpLoginId()).append("','%')");
        if(!StringUtils.isEmpty(orderPageQuery.getOrderIds()))
            sql.append(" and t1.id = ").append(orderPageQuery.getOrderIds());
        if(!StringUtils.isEmpty(orderPageQuery.getErpPO()))
            sql.append(" and t1.erp_po = ").append(orderPageQuery.getErpPO());
        if(!StringUtils.isEmpty(orderPageQuery.getGoodsIds()))
            sql.append(" and t2.goods_id = ").append(orderPageQuery.getGoodsIds());
        if(!StringUtils.isEmpty(orderPageQuery.getSku()))
            sql.append(" and t2.sku = ").append(orderPageQuery.getSku());
        if(!StringUtils.isEmpty(orderPageQuery.getName()))
            sql.append(" and t2.name = ").append(orderPageQuery.getName());
        if(!StringUtils.isEmpty(orderPageQuery.getDateType())){
            if(1 == orderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t2.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.DATE,-3)).append("'");
            if(2 == orderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t2.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.MONTH,-1)).append("'");
            if(3 == orderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t2.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.MONTH,-3)).append("'");
        }
        if(!StringUtils.isEmpty(orderPageQuery.getStatus())){
            if("Refund".equals(orderPageQuery.getStatus()))
                sql.append(" and (t1.after_sale = '售后中' or t1.after_sale = '已售后')");
            else {
                List<String> status = Arrays.stream(orderPageQuery.getStatus().split(",")).map(t -> "'".concat(t).concat("'")).collect(Collectors.toList());
                sql.append(" and t2.order_customer_goods_status in (").append(String.join(",",status)).append(")");
                sql.append(" and (t1.after_sale = '' or t1.after_sale = '未售后')");
            }
        }
    }

    private void buildRefundOrderFilter(RefundOrderPageQuery refundOrderPageQuery, StringBuilder sql) {
        sql.append(" and t2.place_order_user_id like concat('%','").append(RequestContext.getCorpLoginId()).append("','%')");
        if(!StringUtils.isEmpty(refundOrderPageQuery.getOrderIds()))
            sql.append(" and t1.order_customer_id = ").append(refundOrderPageQuery.getOrderIds());
        if(!StringUtils.isEmpty(refundOrderPageQuery.getErpPO()))
            sql.append(" and t1.erp_po = ").append(refundOrderPageQuery.getErpPO());
        if(!StringUtils.isEmpty(refundOrderPageQuery.getGoodsIds()))
            sql.append(" and t2.goods_id = ").append(refundOrderPageQuery.getGoodsIds());
        if(!StringUtils.isEmpty(refundOrderPageQuery.getSku()))
            sql.append(" and t1.sku = ").append(refundOrderPageQuery.getSku());
        if(!StringUtils.isEmpty(refundOrderPageQuery.getName()))
            sql.append(" and t1.name = ").append(refundOrderPageQuery.getName());
        if(!StringUtils.isEmpty(refundOrderPageQuery.getDateType())){
            if(1 == refundOrderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t1.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.DATE,-3)).append("'");
            if(2 == refundOrderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t1.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.MONTH,-1)).append("'");
            if(3 == refundOrderPageQuery.getDateType())
                sql.append(" and t1.createdTime <= '").append(PmUtil.getEndDateStr(Calendar.DATE,0)).append("'")
                        .append(" and  t1.createdTime >= '").append(PmUtil.getStartDateStr(Calendar.MONTH,-3)).append("'");
        }
        if(!StringUtils.isEmpty(refundOrderPageQuery.getStatus())){
            List<String> status = Arrays.stream(refundOrderPageQuery.getStatus().split(",")).map(t -> "'".concat(t).concat("'")).collect(Collectors.toList());
            sql.append(" and t1.order_goods_returns_status in (").append(String.join(",",status)).append(")");
        }
    }

    @POST
    @Path("verificationCode")
    @Operation(summary = "个人中心-图片验证码", tags = CUSTOM_SERVICE)
    public void verificationCode()  {
        Map map= VerificationCodeUtil.getVerificationCode();
        redisTemplate.opsForValue().set(RequestContext.getCorpLoginId().concat(IMG_CODE), ((StringBuffer)map.get("code")).toString(), 5, TimeUnit.MINUTES);
        BufferedImage bufferedImage = (BufferedImage)map.get("imgStream");
        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
        response.setContentType("image/jpeg");
        response.setHeader("Pragma","no-cache");
        response.setHeader("Cache-Control","cache");
        response.setDateHeader("Expires",0);
        try {
            ByteArrayOutputStream outStream =new ByteArrayOutputStream();
            ImageIO.write(bufferedImage,"jpg",outStream);
            String encoded =  "data:image/jpeg;base64,".concat(Base64.getEncoder().encodeToString(outStream.toByteArray()));
            response.getWriter().write(encoded);
        } catch (IOException e) {
            log.error("图片生成异常",e);
        }
    }

    @POST
    @Path("sendSms")
    @Operation(summary = "个人中心-手机验证码", tags = CUSTOM_SERVICE)
    public void sendSms(@Parameter SendSmsDto sendSmsDto){
        Assert.isTrue(!StringUtils.isEmpty(sendSmsDto),"参数不能为空");
        Assert.isTrue(!StringUtils.isEmpty(sendSmsDto.getPhone()),"手机号不能为空");
        String code = PmUtil.createCode();
        redisTemplate.opsForValue().set(RequestContext.getCorpLoginId().concat(SMS_CODE), code, 5, TimeUnit.MINUTES);
        SMSTemplateParamsDto message = SMSTemplateParamsDto.builder()
                .code(code)
                .product("个人中心")
                .build();
        SendSmsUtils.sendSingleSms(sendSmsDto.getPhone(),message, SMSTemplateCodeEnum.INFO_ALTER_AUTH_CODE.text);
    }

    @POST
    @Path("checkCode")
    @Operation(summary = "个人中心-验证码校验", tags = CUSTOM_SERVICE)
    public SingleResponse checkCode(@Parameter CheckCodeDto checkCodeDto){
        Assert.isTrue(Objects.nonNull(checkCodeDto),"参数不能为空");
        String smsCode = redisTemplate.opsForValue().get(RequestContext.getCorpLoginId().concat(SMS_CODE));
        String imgCode = redisTemplate.opsForValue().get(RequestContext.getCorpLoginId().concat(IMG_CODE));
        Assert.isTrue(checkCodeDto.getImageCode().equalsIgnoreCase(imgCode),"图片验证码错误");
        Assert.isTrue(checkCodeDto.getSmsCode().equals(smsCode),"手机验证码错误");
        return SingleResponse.buildSuccess();
    }

    @POST
    @Path("setDefaultAddress")
    @Operation(summary = "个人中心-设置默认地址", tags = CUSTOM_SERVICE)
    public SingleResponse setDefaultAddress(@Parameter QueryIdDto queryIdDto){
        Assert.isTrue(Objects.nonNull(queryIdDto),"参数不能为空");
        Assert.isTrue(!StringUtils.isEmpty(queryIdDto.getId()),"参数不能为空");
        BOList address = BoServiceUtils.findListBySimple(ADDRESS, "default_address", 1, Operator.EQ).getData();
        if(Objects.nonNull(address)&&!CollectionUtils.isEmpty(address.getData())){
            List<Map<String, Object>> maps = address.getData().stream().map(t -> {
                Map<String, Object> map = Maps.newHashMap();
                map.put("id", t.get("id"));
                map.put("default_address", false);
                return map;
            }).collect(Collectors.toList());
            BoServiceUtils.batchUpdateBo(ADDRESS,maps);
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("id",queryIdDto.getId());
        paramMap.put("default_address",true);
        return BoServiceUtils.updateBo(ADDRESS,paramMap);
    }



    @POST
    @Path("setDefaultInvoice")
    @Operation(summary = "个人中心-设置默认发票", tags = CUSTOM_SERVICE)
    public SingleResponse setDefaultInvoice(@Parameter QueryIdDto queryIdDto){
        Assert.isTrue(Objects.nonNull(queryIdDto),"参数不能为空");
        Assert.isTrue(!StringUtils.isEmpty(queryIdDto.getId()),"参数不能为空");
        BOList address = BoServiceUtils.findListBySimple(INVOICE, "default_invoice", 1, Operator.EQ).getData();
        if(Objects.nonNull(address)&&!CollectionUtils.isEmpty(address.getData())){
            List<Map<String, Object>> maps = address.getData().stream().map(t -> {
                Map<String, Object> map = Maps.newHashMap();
                map.put("id", t.get("id"));
                map.put("default_invoice", false);
                return map;
            }).collect(Collectors.toList());
            BoServiceUtils.batchUpdateBo(INVOICE,maps);
        }
        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("id",queryIdDto.getId());
        paramMap.put("default_invoice",true);
        return BoServiceUtils.updateBo(INVOICE,paramMap);
    }

    @POST
    @Path("saveOrUpdateInvoice")
    @Operation(summary = "个人中心-新增发票", tags = CUSTOM_SERVICE)
    public SingleResponse saveOrUpdateInvoice(@Parameter AddInvoiceDto addInvoiceDto){
        Assert.isTrue(Objects.nonNull(addInvoiceDto),"参数不能为空");
        String phoneRegex = "^1[3-9]\\d{9}$";
        String taxNumberRegex = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$";
        Assert.isTrue(!StringUtils.isEmpty(addInvoiceDto.getTax_number())
                &&addInvoiceDto.getTax_number().matches(taxNumberRegex),"纳税人识别号只能是18位数字或大写字母，请检查");
        Assert.isTrue(!StringUtils.isEmpty(addInvoiceDto.getPhone())
                &&addInvoiceDto.getPhone().matches(phoneRegex),"联系电话格式不正确，请输入正确的手机号或带区号的固定电话");
        Map<String, Object> map = BoUtils.bo2Map(addInvoiceDto);
        if(!StringUtils.isEmpty(addInvoiceDto.getId())){
            return BoServiceUtils.updateBo(INVOICE,map);
        }
        map.put("member_id",PmUtil.userFormat());
        map.put("operator",PmUtil.userFormat());
        map.put("default_invoice",false);
        map.put("deleted",false);
        map.put("id", IdWorker.nextId());
        return BoServiceUtils.createBo(INVOICE,map);
    }

    @POST
    @Path("saveOrUpdateAddress")
    @Operation(summary = "个人中心-保存或更新收货地址", tags = CUSTOM_SERVICE)
    public SingleResponse saveOrUpdateAddress(@Parameter AddressDto addressDto){
        Assert.isTrue(Objects.nonNull(addressDto),"参数不能为空");
        if(StringUtils.isEmpty(addressDto.getId())){
            return BoServiceUtils.createBo(ADDRESS,BoUtils.bo2Map(addressDto));
        }
        return BoServiceUtils.updateBo(ADDRESS,BoUtils.bo2Map(addressDto));
    }

}
